home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QRZ! Ham Radio 8
/
QRZ Ham Radio Callsign Database - Volume 8.iso
/
mac
/
files
/
t_sys5
/
92052tar.gz
/
920528.tar
/
remote_net.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-18
|
7KB
|
295 lines
/* @(#) $Header: remote_net.c,v 1.10 91/09/17 22:22:04 deyke Exp $ */
#include <sys/types.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include "global.h"
#include "mbuf.h"
#include "timer.h"
#include "transport.h"
#include "hpux.h"
#include "buildsaddr.h"
struct controlblock {
int fd; /* Socket descriptor */
char buffer[1024]; /* Input buffer */
int bufcnt; /* Number of bytes in buffer */
struct transport_cb *tp; /* Transport handle */
int binary; /* Transfer is binary (no EOL conv) */
};
struct cmdtable {
char *name; /* Command name (lower case) */
int (*fnc) __ARGS((struct controlblock *cp)); /* Command function */
};
static int flisten = -1;
static char *getarg __ARGS((char *line, int all));
static int command_switcher __ARGS((struct controlblock *cp, char *name, struct cmdtable *tableptr));
static void delete_controlblock __ARGS((struct controlblock *cp));
static void transport_try_send __ARGS((struct controlblock *cp));
static void transport_recv_upcall __ARGS((struct transport_cb *tp, int cnt));
static void transport_send_upcall __ARGS((struct transport_cb *tp, int cnt));
static void transport_state_upcall __ARGS((struct transport_cb *tp));
static int ascii_command __ARGS((struct controlblock *cp));
static int binary_command __ARGS((struct controlblock *cp));
static int connect_command __ARGS((struct controlblock *cp));
static void command_receive __ARGS((struct controlblock *cp));
static void accept_connection __ARGS((void *p));
/*---------------------------------------------------------------------------*/
static char *getarg(line, all)
char *line;
int all;
{
char *arg;
int c, quote;
static char *p;
if (line) p = line;
while (isspace(uchar(*p))) p++;
if (all) return p;
quote = '\0';
if (*p == '"' || *p == '\'') quote = *p++;
arg = p;
if (quote) {
if (!(p = strchr(p, quote))) p = "";
} else
while (*p && !isspace(uchar(*p))) {
c = tolower(uchar(*p));
*p++ = c;
}
if (*p) *p++ = '\0';
return arg;
}
/*---------------------------------------------------------------------------*/
static int command_switcher(cp, name, tableptr)
struct controlblock *cp;
char *name;
struct cmdtable *tableptr;
{
int namelen;
namelen = strlen(name);
for (; ; ) {
if (!tableptr->name) return (-1);
if (!strncmp(tableptr->name, name, namelen)) return (*tableptr->fnc)(cp);
tableptr++;
}
}
/*---------------------------------------------------------------------------*/
static void delete_controlblock(cp)
struct controlblock *cp;
{
off_read(cp->fd);
close(cp->fd);
free(cp);
}
/*---------------------------------------------------------------------------*/
static void transport_try_send(cp)
struct controlblock *cp;
{
int cnt;
struct mbuf *bp;
cnt = transport_send_space(cp->tp);
if (cnt <= 0) {
off_read(cp->fd);
return;
}
if (!(bp = alloc_mbuf(cnt))) return;
cnt = read(cp->fd, bp->data, (unsigned) cnt);
if (cnt <= 0) {
free_p(bp);
off_read(cp->fd);
transport_close(cp->tp);
return;
}
bp->cnt = cnt;
transport_send(cp->tp, bp);
}
/*---------------------------------------------------------------------------*/
static void transport_recv_upcall(tp, cnt)
struct transport_cb *tp;
int16 cnt;
{
char buffer[1024];
struct controlblock *cp;
struct mbuf *bp;
cp = (struct controlblock *) tp->user;
transport_recv(tp, &bp, 0);
while ((cnt = pullup(&bp, buffer, sizeof(buffer))) > 0)
if (write(cp->fd, buffer, (unsigned) cnt) != cnt) transport_close(tp);
}
/*---------------------------------------------------------------------------*/
static void transport_send_upcall(tp, cnt)
struct transport_cb *tp;
int16 cnt;
{
struct controlblock *cp;
cp = (struct controlblock *) tp->user;
on_read(cp->fd, (void (*)()) transport_try_send, cp);
}
/*---------------------------------------------------------------------------*/
static void transport_state_upcall(tp)
struct transport_cb *tp;
{
delete_controlblock((struct controlblock *) tp->user);
transport_del(tp);
}
/*---------------------------------------------------------------------------*/
static int ascii_command(cp)
struct controlblock *cp;
{
cp->binary = 0;
return 0;
}
/*---------------------------------------------------------------------------*/
static int binary_command(cp)
struct controlblock *cp;
{
cp->binary = 1;
return 0;
}
/*---------------------------------------------------------------------------*/
static int connect_command(cp)
struct controlblock *cp;
{
char *protocol, *address;
protocol = getarg((char *) 0, 0);
address = getarg((char *) 0, 1);
cp->tp = transport_open(protocol, address, transport_recv_upcall, transport_send_upcall, transport_state_upcall, (char *) cp);
if (!cp->tp) return (-1);
if (!cp->binary) {
cp->tp->recv_mode = EOL_LF;
cp->tp->send_mode = (!strcmp(protocol, "tcp")) ? EOL_CRLF : EOL_CR;
}
on_read(cp->fd, (void (*)()) transport_try_send, cp);
return 0;
}
/*---------------------------------------------------------------------------*/
static void command_receive(cp)
struct controlblock *cp;
{
static struct cmdtable command_table[] = {
"ascii", ascii_command,
"binary", binary_command,
"connect", connect_command,
0, 0
};
char c;
if (read(cp->fd, &c, 1) <= 0) {
delete_controlblock(cp);
return;
}
if (c != '\n') {
cp->buffer[cp->bufcnt++] = c;
if (cp->bufcnt >= sizeof(cp->buffer)) delete_controlblock(cp);
return;
}
cp->buffer[cp->bufcnt] = '\0';
cp->bufcnt = 0;
if (command_switcher(cp, getarg(cp->buffer, 0), command_table))
delete_controlblock(cp);
}
/*---------------------------------------------------------------------------*/
static void accept_connection(p)
void *p;
{
int addrlen;
int fd;
struct controlblock *cp;
struct sockaddr addr;
addrlen = sizeof(addr);
if ((fd = accept(flisten, &addr, &addrlen)) < 0) return;
cp = (struct controlblock *) calloc(1, sizeof (struct controlblock ));
if (!cp) {
close(fd);
return;
}
cp->fd = fd;
on_read(cp->fd, (void (*)()) command_receive, cp);
}
/*---------------------------------------------------------------------------*/
void remote_net_initialize()
{
static char *socketnames[] = {
#if (defined(hpux)||defined(__hpux))
"unix:/tcp/.sockets/netcmd",
#else
"*:4718",
#endif
(char *) 0
};
int addrlen, i;
int arg;
struct sockaddr *addr;
for (i = 0; socketnames[i]; i++) {
if (addr = build_sockaddr(socketnames[i], &addrlen)) {
if ((flisten = socket(addr->sa_family, SOCK_STREAM, 0)) >= 0) {
switch (addr->sa_family) {
case AF_UNIX:
if (!Debug) unlink(addr->sa_data);
break;
case AF_INET:
arg = 1;
setsockopt(flisten, SOL_SOCKET, SO_REUSEADDR, (char *) &arg, sizeof(arg));
break;
}
if (!bind(flisten, addr, addrlen) && !listen(flisten, SOMAXCONN)) {
on_read(flisten, accept_connection, (void *) 0);
} else {
close(flisten);
flisten = -1;
}
}
}
}
}